#include "Board.h"

void Board::initialBoard()
{
	sizeOfTile = 4.0;
	for(size_t i = 1; i <= size; i++)
	{
		vector<Tile> tilesLine;
		int j = 1;
		while(j <= size)
		{
			Tile emptyTile(j, 0, i, sizeOfTile);
			tilesLine.push_back(emptyTile);
			sContent += 'O';
			j++;
		}
		content.push_back(tilesLine);
	}
}

void Board:: render_arrow(GLenum mode, int id)
{
	if (mode == GL_SELECT) 
		glLoadName (id);
	glPushMatrix();
		glRotated(90.0, 0.0, 1.0, 0.0);
		glBegin(GL_TRIANGLE_STRIP);
			glVertex3d(1,0,0);
			glVertex3d(0.25,0,-1);
			glVertex3d(-0.5,0,0);
		glEnd();
			if (mode == GL_SELECT) 
		glLoadName (id);
		glBegin(GL_POLYGON);
			glNormal3d(0.0, 1.0, 0);
			glVertex3d(0.5,0,0.8);
			glVertex3d(0.5,0,0);
			glVertex3d(0,0,0);
			glVertex3d(0,0,0.8);
		glEnd();
	glPopMatrix();
}



int Board::arrows(int i, int id, GLenum mode, int size_t)
{	
   glPushMatrix();
		glTranslated(0, 0.0, sizeOfTile*(i+1));
		render_arrow(mode, id);
   glPopMatrix();

   glPushMatrix();
		glTranslated(sizeOfTile*(i+1), 0.0, 0);
		glRotated(-90,0,1,0);
		render_arrow(mode, id + size_t);
   glPopMatrix();

   glPushMatrix();
		glTranslated(sizeOfTile*(i+1), 0.0, sizeOfTile*(size+1));
		glRotated(90,0,1,0);
		render_arrow(mode, id + (size_t*2));
	glPopMatrix();

	glPushMatrix();
		glTranslated(sizeOfTile*(size+1), 0.0, sizeOfTile*(i+1));
		glRotated(180,0,1,0);
		render_arrow(mode, id + (size_t*3));
	glPopMatrix();

	id++;
	return id;
}

void Board::render(GLenum mode)
{   int arrow_id = size*size+1;
	float sizeOfTile = content[0][0].getSize();
	int counter = 0;
	if (mode == GL_SELECT)
       glPushName(0);
	for(size_t i = 0; i < size; i++)
	{  
	    arrow_id = arrows(i, arrow_id, mode, size);
		float zPos;
		for(size_t j = 0; j < size; j++)
		{
			float xPosDraw = content[i][j].getXPos();
			float yPosDraw = content[i][j].getYPos();
			float zPosDraw = content[i][j].getZPos();
			glPushMatrix();
				glTranslated(xPosDraw*sizeOfTile, yPosDraw, zPosDraw*sizeOfTile);
				counter++;
				content[i][j].drawTile(mode,counter);
				if(content[i][j].getHasPiece())
                      content[i][j].getPiece().render();
			glPopMatrix();
			zPos = zPosDraw;
		}
	}
}

void Board::printBoardOnConsole()
{
	for(size_t i = 0; i < content.size(); i++){
		for(size_t j = 0; j < content[i].size(); j++){
			if(content[i][j].getHasPiece()){
				cout << "[1]";
			}else{
				cout << "[0]";
			}
		}
		cout << endl;
	}
}

void Board::setPieceBoard(Piece test, float posX, float posY)
{
	content[posX][posY].setPiece(test);
	content[posX][posY].setHasPiece(true);
	if(test.getY()>5){
		
		content[posX][posY].setFlag(0);}

}

void Board::shiftRow(int row, string side)
{
	if(side == "right"){
		/* Save a copy of lastTile */
		Tile lastTile = content[row][size-1];
		lastTile.setXPos(1);
		for(size_t i = 0; i < content[row].size(); i++)
		{
			content[row][i].setXPos(i+2);

			if(content[row][i].getHasPiece()){
			content[row][i].setPieceX(-sizeOfTile);		

			}
		}
		/* Delete last element */
		lastTile.setFlag(1);
		if(lastTile.getHasPiece()){
			lastTile.setPieceX(sizeOfTile*(size-1));		
			}

		content[row].pop_back();
		/* Insert first element */
		vector<Tile>::iterator it = content[row].begin();
		content[row].insert(it, lastTile);
	}
	else if (side == "left")
	{
		/* Save a copy of first element os row */
		Tile firstTile = content[row][0];
		firstTile.setXPos(size);
		/* Changing coordinates */
		for(size_t i = 0; i < content[row].size(); i++)
		{
			content[row][i].setXPos(i);
			if(content[row][i].getHasPiece()){
			content[row][i].setPieceX(sizeOfTile);		
			}
		}
		/* Delete first element */
			firstTile.setFlag(1);
			if(firstTile.getHasPiece()){
			firstTile.setPieceX(-sizeOfTile*size);		
			}
		vector<Tile>::iterator it = content[row].begin();
		content[row].erase(it);
		/* Insert firstTile in the end*/
		content[row].push_back(firstTile);
	}
}

void Board::shiftColumn(int column, string side)
{
	if(side == "up")
	{
		/* Create copy of first tile of specified column */
		Tile firstTile = content[0][column];
		firstTile.setZPos(size);
		for(size_t i = 0; i < content.size(); i++)
		{
			Tile nextTile;
			if(i < 6)
			{
				nextTile = content[i+1][column];
				/* Changing coordinates of tiles on column */
				nextTile.setZPos(i+1);
				if(nextTile.getHasPiece()){
			       nextTile.setPieceZ(sizeOfTile);		
			}
			}
			/* Erasing element to insert new one */
				firstTile.setFlag(1);
			if(firstTile.getHasPiece()){
			firstTile.setPieceZ(-sizeOfTile*(size-1));		
			}
			vector<Tile>::iterator it = content[i].begin()+column;
			content[i].erase(it);
			it = content[i].begin()+column;
			/* Inserting element */
			if (i < 6)
				content[i].insert(it, nextTile);
			else
				content[i].insert(it, firstTile);
		}
	}
	else if(side == "down")
	{
		/* Creating copy of last tile */
		Tile lastTile = content[size-1][column];
		lastTile.setZPos(1);
		for(int i = content.size()-1; i >= 0; i--)
		{
			Tile nextTile;
			if(i > 0)
			{
				nextTile = content[i-1][column];
				/* Changing coordinates of tiles on column */
				nextTile.setZPos(i+1);

					if(nextTile.getHasPiece()){
			       nextTile.setPieceZ(-sizeOfTile);		
			}
			}

		lastTile.setFlag(1);
		if(lastTile.getHasPiece()){
			lastTile.setPieceZ(sizeOfTile*(size-1));		
			}

			/* Erasing element to insert new one */
			vector<Tile>::iterator it = content[i].begin()+column;
			content[i].erase(it);
			it = content[i].begin()+column;
			/* Inserting element */
			if (i > 0)
				content[i].insert(it, nextTile);
			else
				content[i].insert(it, lastTile);
		}
	}
}

void Board::convertContentS()
{
	int pos = 0;
	for(size_t i = 0; i < content.size(); i++)
	{
		for(size_t j = 0; j < content[i].size(); j++)
		{
			if(!content[i][j].getHasPiece())
			{
				if(sContent[pos] != 'O')
				{
					Piece p(0,7,0, sContent[pos], sizeOfTile);
					setPieceBoard(p, i, j);
				}
			}
			else
			{
				if(sContent[pos] == 'O')
				{
					Tile emptyTile(j+1, 0, i+1, sizeOfTile);
					content[i][j] = emptyTile;
				}
			}
			pos++;
		}
	}
}

string Board::board2String()
{
	int pos = 0;
	for(size_t i = 0; i < content.size(); i++)
	{
		for(size_t j = 0; j < content[i].size(); j++)
		{
			if(content[i][j].getHasPiece())
			{
				sContent[pos] = content[i][j].getPiece().getPlayerChar();
			}
			else
			{
				sContent[pos] = 'O';
			}
			pos++;
		}
	}

	pos = 0;
	string result = "[";

	for(size_t i = 0; i < content.size(); i++)
	{
		result += '[';
		for(size_t j = 0; j < content[i].size(); j++)
		{
			if(j == content[i].size()-1)
			{
				string inner = "'";
				inner += sContent[pos];
				inner += "'";
				result += inner;
			}
			else
			{
				string inner = "'";
				inner += sContent[pos];
				inner += "',";
				result += inner;
			}
			pos++;
		}

		if(i == content.size()-1)
			result += ']';
		else
			result += "],";
	}

	result += ']';

	return result;
}

void Board::clearBoard()
{
	for(size_t i = 0; i < content.size(); i++)
	{
		for(size_t j = 0; j < content[i].size(); j++)
		{
			if(content[i][j].getHasPiece())
			{
				Tile emptyTile(j+1, 0, i+1, sizeOfTile);
				content[i][j] = emptyTile;
			}
		}
	}
}